﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services;

namespace AstoriaPlus
{
	/// <summary>
	/// Interface implemented by behaviors that intercept the Astoria pipeline to 
	/// augment the service with cross-cutting concerns.
	/// </summary>
	/// <remarks>
	/// The <see cref="IPipelineContext"/> parameter in all methods is the same instance 
	/// for the entire processing of a request, whether it is batched or not.
	/// </remarks>
	public interface IPipelineBehavior
	{
		/// <summary>
		/// Invoked at the beginning of the pipeline request, whether 
		/// it is a batch operation or not. This is the very first 
		/// call in the pipeline lifetime.
		/// </summary>
		void ProcessingRequest(IPipelineContext pipelineContext, DataServiceOperationContext operationContext);

		/// <summary>
		/// Invoked at the start of a batch operation.
		/// </summary>
		void ProcessingChangeset(IPipelineContext pipelineContext, DataServiceOperationContext operationContext);

		/// <summary>
		/// Invoked when a batch operation has finished processing.
		/// </summary>
		void ProcessedChangeset(IPipelineContext pipelineContext, DataServiceOperationContext operationContext);

		/// <summary>
		///	Invoked at the end of the pipeline processing, whether the 
		///	request was a batch operation or noth. This is the very last 
		///	call in the pipeline lifetime.
		/// </summary>
		void ProcessedRequest(IPipelineContext pipelineContext, DataServiceOperationContext operationContext);

		/// <summary>
		/// Invoked when an exception happened during processing.
		/// </summary>
		void HandleException(IPipelineContext pipelineContext, HandleExceptionArgs args);

		/// <summary>
		/// Invoked at the beginning of the processing of a 
		/// changeset (if the request is a batch) as well as 
		/// for each entity. This will be called multiple times 
		/// for a batch, but only once for a single-entity request. 
		/// This is invoked always (in both cases) after the <see cref="ProcessingRequest"/> 
		/// and before the <see cref="ProcessedRequest"/> method.
		/// </summary>
		void StartProcessingRequest(IPipelineContext pipelineContext, ProcessRequestArgs args);
	}
}